<script setup lang="ts">
import {
  reqAddOrUpdateSpu,
  reqSpuInfo,
  reqSpuAllSaleAttrList,
} from '@/api/product/spu'
import { computed, nextTick, reactive, ref, watch } from 'vue'
import { ElMessage, type UploadProps, UploadUserFile } from 'element-plus'
import { reqAllTrademarkList } from '@/api/product/trademark'
import type { Trademark } from '@/api/product/trademark/type.ts'
import type { ResponseData } from '@/api/type.ts'
import { BaseSpuSaleAttr, SPU, spuSaleAttr } from '@/api/product/spu/type.ts'

const props = defineProps({
  scene: Number,
})

const $emit = defineEmits(['update:scene'])

const spu = reactive<SPU>({
  id: '',
  spuName: '',
  description: '',
  category3Id: '',
  tmId: '',
  spuSaleAttrList: [],
  spuImageList: [],
  spuPosterList: [],
})

const trademarkList = ref<Trademark[]>([])
const spuAllSaleAttrList = ref<BaseSpuSaleAttr[]>([])

// spu未拥有的销售属性值
const unownedSaleAttrList = computed(() => {
  /*
  all：[颜色，版本，尺寸]
  已有：[颜色，版本]
  对all的每一个属性，判断是不是不在已有的里面
   */
  return spuAllSaleAttrList.value.filter((attr) => {
    return spu.spuSaleAttrList.every((ownAttr) => {
      return ownAttr.saleAttrName != attr.name
    })
  })
})

// 选择添加的销售属性
const saleAttrSelected = ref<string>('')

// 新增的销售属性值
const newSaleAttrValue = ref<string>('')
const attrValueInputRef = ref<any>()

// spu上传图片列表
const spuImgList = ref<UploadUserFile[]>([])
const dialogImageUrl = ref<string>('')
const dialogVisible = ref<boolean>(false)

const getSpu = async (id: number) => {
  try {
    const { code, data, message }: ResponseData<SPU> = await reqSpuInfo(id)
    if (code == 200) {
      Object.assign(spu, data)
      spuImgList.value = spu.spuImageList.map((img) => {
        return {
          name: img?.imgName,
          url: img?.imgUrl,
        }
      })
    } else {
      ElMessage.error(message)
    }
  } catch (err: any) {
    ElMessage.error(err?.message)
  }
}

const resetSpu = () => {
  spu.id = ''
  spu.spuName = ''
  spu.description = ''
  spu.tmId = ''
  spu.category3Id = ''
  spu.spuImageList = []
  spu.spuSaleAttrList = []

  spuImgList.value = []
}

const getTrademarkList = async () => {
  try {
    const { code, data, message } = await reqAllTrademarkList()
    if (code == 200) {
      trademarkList.value = data
    } else {
      ElMessage.error(message)
    }
  } catch (err: any) {
    ElMessage.error(err?.message)
  }
}

const getSpuSaleAttrList = async () => {
  try {
    const { code, data, message } = await reqSpuAllSaleAttrList()

    if (code == 200) {
      spuAllSaleAttrList.value = data
    } else {
      ElMessage.error(message)
    }
  } catch (err: any) {
    ElMessage.error(err?.message)
  }
}

const initHasSpu = (id: number) => {
  getSpu(id)
  getTrademarkList()
  getSpuSaleAttrList()
}

const initAddSpu = (c3Id: number) => {
  spu.category3Id = c3Id
  getTrademarkList()
  getSpuSaleAttrList()
}

const beforeImgUpload: UploadProps['beforeUpload'] = (rawFile: any) => {
  if (!/^image\/(jpe?g|png|gif)$/.test(rawFile.type)) {
    ElMessage.error('请上传图片，格式jpg/png/gif')
    return false
  }

  if (rawFile.size > 4 * 1024 * 1024) {
    ElMessage.error('图片太大了，不超过4M')
    return false
  }
  return true
}

const handleImgPreview = (uploadFile: UploadUserFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}

const handleImgRemove = (
  uploadFile: UploadUserFile,
  uploadFiles: UploadUserFile[],
) => {
  console.log(uploadFile, uploadFiles)
}

// 点击添加销售属性按钮回调
const onAddSaleAttr = () => {
  const [baseSaleAttrId, saleAttrName] = saleAttrSelected.value.split(':')

  spu.spuSaleAttrList.push({
    spuId: spu.id as number,
    baseSaleAttrId: parseInt(baseSaleAttrId),
    saleAttrName,
    spuSaleAttrValueList: [],
    flag: false,
  })

  saleAttrSelected.value = ''
}

// 点击删除销售属性按钮回调
const onDeleteSaleAttr = ($index: number) => {
  spu.spuSaleAttrList.splice($index, 1)
}

// 点击添加销售属性值，进入编辑模式
const toEdit = (row: spuSaleAttr) => {
  row.flag = true
  newSaleAttrValue.value = ''

  nextTick(() => {
    attrValueInputRef.value.focus()
  })
}

// 退出销售属性值编辑模式，进入查看模式
const toLook = (row: spuSaleAttr) => {
  if (newSaleAttrValue.value.trim() == '') {
    ElMessage.warning('属性值不能为空')
    row.flag = false
    return
  }
  let repeat = row.spuSaleAttrValueList.find((value) => {
    return value.saleAttrValueName == newSaleAttrValue.value
  })
  if (repeat) {
    ElMessage.warning('属性值不能重复')
    row.flag = false
    return
  }
  const { spuId, baseSaleAttrId, saleAttrName } = row
  row.spuSaleAttrValueList.push({
    spuId,
    baseSaleAttrId,
    saleAttrName,
    saleAttrValueName: newSaleAttrValue.value,
  })
  row.flag = false
}

const onConfirm = async () => {
  // 图片list数据转换
  spu.spuImageList = spuImgList.value.map((img: any) => {
    return {
      imgName: img.name,
      imgUrl: (img.response && img.response.data) || img.url,
    }
  })

  try {
    const { code, data, message } = await reqAddOrUpdateSpu(spu)

    if (code == 200) {
      ElMessage({
        type: 'success',
        message: spu.id ? '修改成功' : '添加成功',
      })
      $emit('update:scene', 0)
    } else {
      ElMessage.error(data ? data : message)
    }
  } catch (err: any) {
    console.log(err)
    ElMessage.error(err?.message)
  }
}

const onCancel = () => {
  $emit('update:scene', 0)
}

watch(
  () => props.scene,
  (newVal) => {
    if (newVal == 0) {
      resetSpu()
    }
  },
)

defineExpose({
  initHasSpu,
  initAddSpu,
  resetSpu,
})
</script>

<template>
  <el-form label-width="100">
    <el-form-item label="SPU名称">
      <el-input v-model="spu.spuName" placeholder="请输入SPU名称"></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌">
      <el-select v-model="spu.tmId" placeholder="请选择">
        <el-option
          v-for="item in trademarkList"
          :key="item.id"
          :value="item.id as number"
          :label="item.tmName"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述">
      <el-input
        v-model="spu.description"
        type="textarea"
        placeholder=""
      ></el-input>
    </el-form-item>
    <el-form-item label="SPU图片">
      <el-upload
        v-model:file-list="spuImgList"
        list-type="picture-card"
        action="/api/admin/product/fileUpload"
        :before-upload="beforeImgUpload"
        :on-preview="handleImgPreview"
        :on-remove="handleImgRemove"
        class="image-uploader"
      >
        <el-icon class="image-uploader-icon"><Plus /></el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img
          w-full
          :src="dialogImageUrl"
          alt="Preview Image"
          style="width: 100%"
        />
      </el-dialog>
    </el-form-item>
    <el-form-item label="SPU销售属性">
      <el-select
        v-model="saleAttrSelected"
        :placeholder="
          unownedSaleAttrList.length > 0
            ? `还有${unownedSaleAttrList.length}个未选择`
            : '无'
        "
      >
        <el-option
          v-for="item in unownedSaleAttrList"
          :key="item.id"
          :value="`${item.id}:${item.name}`"
          :label="item.name"
        ></el-option>
      </el-select>
      <el-button
        type="primary"
        icon="plus"
        :disabled="!saleAttrSelected"
        @click="onAddSaleAttr"
        style="margin-left: 10px"
      >
        添加属性
      </el-button>
      <el-table :data="spu.spuSaleAttrList" border>
        <el-table-column type="index" label="序号" width="80" align="center" />
        <el-table-column prop="saleAttrName" label="销售属性名称" width="150" />
        <el-table-column prop="spuSaleAttrValueList" label="销售属性值">
          <template #default="{ row, $index }">
            <el-tag
              v-for="(item, index) in row?.spuSaleAttrValueList"
              :key="index"
              @close="row?.spuSaleAttrValueList.splice(index, 1)"
              closable
            >
              {{ item?.saleAttrValueName }}
            </el-tag>
            <el-input
              v-if="row.flag"
              v-model="newSaleAttrValue"
              ref="attrValueInputRef"
              placeholder="请输入属性值"
              @blur="toLook(row)"
              size="small"
              style="width: 100px"
            ></el-input>
            <el-button
              v-else
              type="primary"
              size="small"
              icon="plus"
              @click="toEdit(row)"
            />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150">
          <template #default="{ $index }">
            <el-button
              type="danger"
              size="small"
              icon="delete"
              title="删除属性"
              @click="onDeleteSaleAttr($index)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="onConfirm">保存</el-button>
      <el-button @click="onCancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<style scoped lang="scss"></style>
